package ru.romannep.pc.chopperbattle;

import java.awt.BorderLayout;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

class ServerFrame extends JFrame implements ServerLog {

    JTextArea messageArea;
    JTextField commandField;

    ServerFrame() {
        super("server console");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(400, 400);

        JPanel framePanel = new JPanel(new BorderLayout(5, 5));

        messageArea = new JTextArea();
        messageArea.setEditable(false);
        framePanel.add(new JScrollPane(messageArea), BorderLayout.CENTER);

        JButton stopButton = new JButton("Stop server");
        stopButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                ChopperBattleGameServer.getGameServer().stopServer();
            }
        });
        framePanel.add(stopButton, BorderLayout.SOUTH);

//        commandField = new JTextField();
//        commandField.addKeyListener(new KeyAdapter() {
//
//            @Override
//            public void keyPressed(KeyEvent k) {
//                switch (k.getKeyCode()) {
//                    case KeyEvent.VK_ENTER:
////                        for (ClientConnection cc : clientConnections) {
////                            cc.sendMessage(new NetworkMessage(0, commandField.getText()));
////                        }
//                        log("->" + commandField.getText());
//                        commandField.setText("");
//                        break;
//                }
//
//            }
//        });
        //framePanel.add(commandField, BorderLayout.SOUTH);

        JButton startButton = new JButton("Start server");
        startButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                ChopperBattleGameServer.getGameServer().startServer();
            }
        });
        framePanel.add(startButton, BorderLayout.NORTH);

        add(framePanel);
        setVisible(true);

        ChopperBattleGameServer.getGameServer().setServerLog(this);
    }

    @Override
    public void log(String text) {
        messageArea.append("\n" + text);
        messageArea.setCaretPosition(messageArea.getDocument().getLength());
        //messageArea.sc
    }
}

interface ServerLog {

    void log(String s);
}

class ChopperBattleGameServer {

    private ServerLog serverLog;
    int serverPort = 3344;
    ServerSocket serverSocket;
    Thread serverSocketThread;
    ArrayList<ChopperBattlePlayer> players = new ArrayList<ChopperBattlePlayer>();

    class ServerSocketHandler implements Runnable {

        @Override
        public void run() {
            try {
                serverSocket = new ServerSocket(serverPort);
                log("listening: " + serverPort);

                while (true) {
                    Socket client = serverSocket.accept();
                    log("connected: " + client.getInetAddress());
                    players.add(new ChopperBattlePlayer(client));
                }
            } catch (IOException ex) {
                log("Err " + ex);
            }
        }
    }

    public void setServerLog(ServerLog log) {
        serverLog = log;
    }

    public void startServer() {
        if (serverSocketThread == null) {
            serverSocketThread = new Thread(new ServerSocketHandler());
            serverSocketThread.start();
        } else {
            log("Already started!");
        }
    }

    public void stopServer() {
        try {
            serverSocket.close();
            Iterator<ChopperBattlePlayer> i = players.iterator();
            while (i.hasNext()) {
                ChopperBattlePlayer player = i.next();
                player.disconnect();
                i.remove();
            }
        } catch (IOException ex) {
            log("Err stoping server " + ex);
        }
    }

    public void log(String s) {
        if (gameServer.serverLog == null) {
            System.out.println(s);

        } else {
            serverLog.log(s);
        }
    }

    public void removePlayer(ChopperBattlePlayer player) {
        chatMessage("disconnected!", player);
        players.remove(player);
    }
    
    public void chatMessage(String message, ChopperBattlePlayer sender){
        
        for (ChopperBattlePlayer player: players){
            if (player != sender){
                player.sendChatMessage(sender.name + ": " + message);
            }
        }
        
    }
    
    public void listOnlinePlayers(ChopperBattlePlayer sender) {
        String onlinePlayers = "";
        for (ChopperBattlePlayer player: players){
            if (player != sender){
                onlinePlayers += player.name + ", ";
            }
        }
        sender.sendChatMessage("Online players: " + onlinePlayers);
        
    }
    
    public void sendGameData(ArrayList<ChopperCommands> commands, ChopperBattlePlayer sender) {
        for (ChopperBattlePlayer player: players){
            if (player != sender){
                //System.out.println("GS in data com[0]=" + commands.get(0).gameCircle + " com = " + commands);
                player.sendGameData(commands);
            }
        }
        
    }
   
    public void startGame(){
        if (players.size() == 2) {
            for (ChopperBattlePlayer player : players) {
                player.sendMessage(new NetworkMessage(MessageType.START_GAME, null));
            }
            //players.get(1).sendMessage(new NetworkMessage(MessageType.START_GAME, null));
        }
    }

    
    private ChopperBattleGameServer() {
        //serverFrame = new ServerFrame();
    }
    
    private static ChopperBattleGameServer gameServer;

    public static ChopperBattleGameServer getGameServer() {

        if (gameServer == null) {
            gameServer = new ChopperBattleGameServer();
        }
        return gameServer;

    }
}
